<template>
    <div class="hash-container">
        <!-- 左侧输入区域 -->
        <n-card class="input-card">
            <template #header>
                <div class="card-header">
                    <span>输入</span>
                    <n-select
                        v-model:value="inputType"
                        :options="inputTypeOptions"
                        class="input-type-select"
                    />
                </div>
            </template>
            
            <n-space vertical>
                <!-- 文本输入 -->
                <template v-if="inputType === 'text'">
                    <n-input 
                        v-model:value="inputText" 
                        type="textarea" 
                        placeholder="请输入要计算哈希的文本"
                        :autosize="{ minRows: 3, maxRows: 10 }" 
                        @update:value="calculateHash" 
                    />
                </template>

                <!-- 文件输入 -->
                <template v-else>
                    <div class="file-input">
                        <n-upload
                            :show-file-list="false"
                            @change="handleFileChange"
                            accept="*/*"
                        >
                            <n-button>选择文件</n-button>
                        </n-upload>
                        <span v-if="selectedFile" class="file-name">
                            {{ selectedFile.name }}
                            <span class="file-size">({{ formatFileSize(selectedFile.size) }})</span>
                        </span>
                    </div>
                </template>

                <n-button @click="clearInput">
                    清空
                </n-button>
            </n-space>
        </n-card>

        <!-- 右侧哈希值显示区域 -->
        <n-card title="哈希值" class="hash-card">
            <n-space vertical>
                <div class="hash-item" v-for="hash in hashResults" :key="hash.type">
                    <div class="hash-header">
                        <span class="hash-label">{{ hash.type }}:</span>
                        <n-button text type="primary" size="tiny" @click="copyToClipboard(hash.value)"
                            :disabled="!hash.value">
                            复制
                        </n-button>
                    </div>
                    <div class="hash-value">
                        {{ hash.value || '-' }}
                    </div>
                </div>
            </n-space>
        </n-card>
    </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import CryptoJS from 'crypto-js'
import view from '@renderer/util/ui/ViewUtil'

const inputType = ref<'text' | 'file'>('text')
const inputTypeOptions = [
    { label: '文本', value: 'text' },
    { label: '文件', value: 'file' }
]
const inputText = ref('')
const selectedFile = ref<File | null>(null)
const hashResults = ref([
    { type: 'MD5', value: '' },
    { type: 'SHA1', value: '' },
    { type: 'SHA256', value: '' },
    { type: 'SHA512', value: '' }
])

// 格式化文件大小
function formatFileSize(bytes: number): string {
    if (bytes === 0) return '0 B'
    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 处理文件选择
function handleFileChange(data: { file: File, fileList: File[] }) {
    if (!data.file || !data.file.file) return
    
    const file = data.file.file as File
    selectedFile.value = file
    
    // 读取文件内容并计算哈希
    const reader = new FileReader()
    reader.onload = (e) => {
        if (!e.target?.result) return
        
        const wordArray = CryptoJS.lib.WordArray.create(e.target.result as ArrayBuffer)
        calculateFileHash(wordArray)
    }
    
    reader.onerror = () => {
        view.alertErrorMessage('文件读取失败')
        selectedFile.value = null
    }
    
    reader.readAsArrayBuffer(file)
}

// 计算文件哈希
function calculateFileHash(wordArray: CryptoJS.lib.WordArray) {
    hashResults.value = [
        { type: 'MD5', value: CryptoJS.MD5(wordArray).toString() },
        { type: 'SHA1', value: CryptoJS.SHA1(wordArray).toString() },
        { type: 'SHA256', value: CryptoJS.SHA256(wordArray).toString() },
        { type: 'SHA512', value: CryptoJS.SHA512(wordArray).toString() }
    ]
}

// 计算文本哈希
function calculateHash() {
    if (!inputText.value) {
        hashResults.value = hashResults.value.map(hash => ({ ...hash, value: '' }))
        return
    }

    hashResults.value = [
        { type: 'MD5', value: CryptoJS.MD5(inputText.value).toString() },
        { type: 'SHA1', value: CryptoJS.SHA1(inputText.value).toString() },
        { type: 'SHA256', value: CryptoJS.SHA256(inputText.value).toString() },
        { type: 'SHA512', value: CryptoJS.SHA512(inputText.value).toString() }
    ]
}

// 清空输入
function clearInput() {
    inputText.value = ''
    selectedFile.value = null
    hashResults.value = hashResults.value.map(hash => ({ ...hash, value: '' }))
}

// 复制到剪贴板
async function copyToClipboard(text: string) {
    try {
        await navigator.clipboard.writeText(text)
        view.alertSuccessMessage('复制成功')
    } catch (err) {
        view.alertErrorMessage('复制失败')
    }
}
</script>

<style scoped>
.hash-container {
    padding: 20px;
    display: flex;
    gap: 20px;
    height: 100%;
}

.input-card,
.hash-card {
    flex: 1;
    min-width: 0;
}

.card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
}

.input-type-select {
    width: 100px;
}

.file-input {
    display: flex;
    gap: 8px;
    align-items: center;
    padding: 16px;
    border: 1px dashed var(--border-color);
    border-radius: 4px;
}

.file-name {
    color: var(--text-color-2);
    font-size: 14px;
}

.file-size {
    color: var(--text-color-3);
    margin-left: 8px;
}

.hash-item {
    width: 100%;
    background-color: var(--n-card-color);
    border-radius: 3px;
    padding: 8px;
}

.hash-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 4px;
}

.hash-label {
    font-weight: bold;
    color: var(--n-text-color-2);
}

.hash-value {
    font-family: monospace;
    word-break: break-all;
    font-size: 0.9em;
    color: var(--n-text-color-1);
    background-color: var(--n-card-color);
    padding: 4px 8px;
    border-radius: 2px;
}

:deep(.n-input) {
    width: 100%;
}
</style>